package be.castanea.client.controller;

import be.castanea.client.model.Self;
import be.castanea.client.services.util.GenericCommand;
import be.castanea.client.services.*;
import be.castanea.common.util.GenericEvent;
import be.castanea.common.*;
import be.castanea.common.util.PositionEvent;
import com.jme.util.GameTaskQueueManager;
import com.jme.util.Timer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Castanea
 * 2009
 * @author Geert van Leemputten, Steven Rymenans, Bart Van Hooydonck
 */
public class FrontController {

    private static FrontController instance;
    private Map<String, List<Class>> actions;

    private FrontController() {
        actions = new HashMap<String, List<Class>>();
        addAction(MovementChangedEvent.class, ChangeMovement.class);
        addAction(JoinEvent.class, AddMob.class);
        addAction(PartEvent.class, RemoveMob.class);
        addAction(JoinReplyEvent.class, AddMob.class);
    }

    private void addAction(Class event, Class action) {
        String eventName = event.getName();
        if (actions.get(eventName) == null) {
            actions.put(eventName, new ArrayList<Class>());
        }
        actions.get(eventName).add(action);
    }

    public static FrontController getInstance() {
        if (instance == null) {
            instance = new FrontController();
        }
        return instance;
    }

    public void dispatchEvent(final GenericEvent event) {
        if (event.getOriginator().equalsIgnoreCase(Self.getInstance().getName())) {
            return;
        }

        String type = event.getClass().getName();
        System.out.println("RECEIVED " + event + " FROM " + event.getOriginator());
        for (final Class actionClass : actions.get(type)) {
            GameTaskQueueManager.getManager().update(new Callable<Object>() {

                public Object call() throws Exception {
                    try {
                        GenericCommand command = (GenericCommand) ClassLoader.getSystemClassLoader().loadClass(actionClass.getCanonicalName()).newInstance();
                        command.setEvent(event);
                        float interpolation = Timer.getTimer().getTimePerFrame();
                        command.execute(interpolation);
                    } catch (InstantiationException ex) {
                        Logger.getLogger(FrontController.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IllegalAccessException ex) {
                        Logger.getLogger(FrontController.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (ClassNotFoundException ex) {
                        Logger.getLogger(FrontController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    return null;
                }
            });
        }
    }
}
